/*
* Poppy Game Engine - https://pgetemplate.googlecode.com/svn/
* -----------------------------------------------------------------------
* Licensed under the BSD license, see LICENSE in PSPSDK root for details.
*
* Copyright (c) 2008 Poppy
*/

#pragma once

namespace PGEMain
{

	template <typename T>
	class CPointer
	{

	public:

		CPointer() : m_pObject(0) {}

		CPointer(const CPointer<T>& ptr)
		{
			if( ptr.m_pObject )
				ptr.m_pObject->AddRef();
			m_pObject = ptr.m_pObject;
		}

		CPointer(T * pObj)
		{
			if(m_pObject)
				m_pObject->AddRef();
			m_pObject = pObj;
		}

		~CPointer()
		{
			if(m_pObject)
				m_pObject->Release();
		}

		CPointer<T>& operator = ( const CPointer<T>& ptr )
		{
			if(ptr.m_pObject)
				ptr.m_pObject->AddRef();
			if(m_pObject)
				m_pObject->Release();
			m_pObject = ptr.m_pObject;
			return *this;
		}

		CPointer<T>& operator = (T * pObj)
		{
			if(pObj)
				pObj->AddRef();
			if(m_pObject)
				m_pObject->Release();
			m_pObject = pObj;
			return *this;
		}

		bool operator == ( const CPointer<T>& ptr ) const
		{
			return m_pObject == ptr.m_pObject;
		}

		bool operator != ( const CPointer<T>& ptr ) const
		{
			return m_pObject != ptr.m_pObject;
		}

		T& operator * ()
		{    
			return *m_pObject;   
		}

		const T& operator * () const
		{    
			return *m_pObject;   
		}

		T* operator -> ()
		{    
			return m_pObject;   
		}

		const T* operator -> () const
		{    
			return m_pObject;   
		}

		operator T * ()
		{
			return m_pObject;
		}

		operator const T * () const
		{
			return m_pObject;
		}

		const static CPointer<T> null;

	protected:
		T * m_pObject;
	};

	template <typename T>
	const CPointer<T> CPointer<T>::null;

#define PGESmartPointer(classname) \
	class classname; \
	typedef CPointer<classname> classname##Ptr

}
